﻿using System;
using System.Collections.Generic;

namespace Zo.Caching
{
    /// <summary>
    /// 缓存管理器
    /// </summary>
    public interface ICacheManager
    {
        /// <summary>
        /// 获得所有 Key。
        /// </summary>
        IEnumerable<string> Keys { get; }

        /// <summary>
        /// 增加缓存值。
        /// </summary>
        /// <typeparam name="TValue">类型。</typeparam>
        /// <param name="key">键对象。</param>
        /// <param name="value">值对象。</param>
        /// <returns>是否成功，成功返回 False，否则返回 True。</returns>
        bool Add<TValue>(string key, TValue value);

        /// <summary>
        /// 获取缓存值。
        /// </summary>
        /// <typeparam name="TValue">值类型。</typeparam>
        /// <param name="key">键对象。</param>
        /// <returns>值对象。</returns>
        TValue Get<TValue>(string key);

        /// <summary>
        /// 获取缓存值，如果不存在，则添加缓存。
        /// </summary>
        /// <typeparam name="TValue">值类型。</typeparam>
        /// <param name="key">键对象。</param>
        /// <param name="acquire">获得值对象的委托。</param>
        /// <returns>值对象。</returns>
        TValue GetOrAdd<TValue>(string key, Func<TValue> acquire);

        /// <summary>
        /// 获取缓存值，如果不存在，则添加缓存。
        /// </summary>
        /// <typeparam name="TValue">值类型。</typeparam>
        /// <param name="key">键对象。</param>
        /// <param name="acquire">获得值对象的委托。</param>
        /// <param name="validFor">过期时长。</param>
        /// <returns>值对象。</returns>
        TValue GetOrAdd<TValue>(string key, Func<TValue> acquire, TimeSpan validFor);

        /// <summary>
        /// 设置缓存值。
        /// </summary>
        /// <typeparam name="TValue">值类型。</typeparam>
        /// <param name="key">键对象。</param>
        /// <param name="value">值对象。</param>
        void Set<TValue>(string key, TValue value);

        /// <summary>
        /// 设置缓存值。
        /// </summary>
        /// <typeparam name="TValue">值类型。</typeparam>
        /// <param name="key">键对象。</param>
        /// <param name="value">值对象。</param>
        /// <param name="timeOut">有效时长。</param>
        void Set<TValue>(string key, TValue value, TimeSpan timeOut);

        /// <summary>
        /// 使用并发锁设置缓存值。
        /// </summary>
        /// <typeparam name="TValue">值类型。</typeparam>
        /// <param name="key">键对象。</param>
        /// <param name="action">缓存值修改方法。</param>
        /// <param name="timeOut">缓存的有效时长。</param>
        /// <param name="lockTimeOut">锁的有效时长。</param>
        void SetLock<TValue>(string key, Func<TValue, TValue> action, TimeSpan timeOut, TimeSpan lockTimeOut);

        /// <summary>
        /// 移除缓存值。
        /// </summary>
        /// <param name="key">键对象。</param>
        bool Remove(string key);

        /// <summary>
        /// 移除缓存值。
        /// </summary>
        /// <typeparam name="TValue">值类型</typeparam>
        /// <param name="key">键对象。</param>
        /// <param name="result">值对象。</param>
        /// <returns>移除是否成功。</returns>
        bool Remove<TValue>(string key, out TValue result);

        /// <summary>
        /// 清空缓存。
        /// </summary>
        void Clear();

        #region 数值操作

        /// <summary>
        /// 根据指定的Key，将值加1(仅整型有效)。
        /// </summary>
        /// <param name="key">键对象。</param>
        void IncrementValue(string key);

        /// <summary>
        /// 根据指定的Key，将值加上指定值(仅整型有效)。
        /// </summary>
        /// <param name="key">键对象。</param>
        /// <param name="value">值对象。</param>
        void IncrementValueBy(string key, int value);

        /// <summary>
        /// 根据指定的Key，将值减1(仅整型有效)。
        /// </summary>
        /// <param name="key">键对象。</param>
        void DecrementValue(string key);

        /// <summary>
        /// 根据指定的Key，将值减去指定值(仅整型有效)。
        /// </summary>
        /// <param name="key">键对象。</param>
        /// <param name="value">值对象。</param>
        void DecrementValueBy(string key, int value);

        #endregion 数值操作

        #region 集合操作

        /// <summary>
        /// 添加一个项到内部的List<T>。
        /// </summary>
        /// <param name="listId">键对象。</param>
        /// <param name="value">值对象。</param>
        void AddItemToList(string listId, string value);

        /// <summary>
        /// 一次过将参数中的List<T>中的多个值添加入内部的List<T>。
        /// </summary>
        /// <param name="listId">键对象。</param>
        /// <param name="value">值对象。</param>
        void AddRangeToList(string listId, IEnumerable<string> value);

        /// <summary>
        /// 移除指定ListId的内部List<T>中第二个参数值相等的那一项。
        /// </summary>
        /// <param name="listId">键对象。</param>
        /// <param name="value">值对象。</param>
        void RemoveItemFromList(string listId, string value);

        /// <summary>
        /// 获取指定ListId的内部List<T>的所有值。
        /// </summary>
        /// <param name="listId">键对象。</param>
        /// <returns>值对象。</returns>
        IEnumerable<string> GetAllItemsFromList(string listId);

        #endregion 集合操作
    }
}